---
title: "Row Sorting"
description: "Sort row data in the $framework Data Grid. Customise row sorting with a custom comparator. Sort by multiple columns and apply post sorting for additional control."
---

This page describes how to sort row data in the grid and how you can customise that sorting to match your requirements.

## Sorting

Sorting is enabled by default for all columns. You can sort a column by clicking on the column header. To enable / disable
sorting per column use the `sortable` column definition attribute.

```{% frameworkTransform=true %}
const gridOptions = {
    columnDefs: [
        { field: 'name' },
        { field: 'age' },
        // disable sorting by address
        { field: 'address', sortable: false },
    ],
}
```

To disable sorting for all columns, set sorting in the [default column definition](./column-definitions/).

```{% frameworkTransform=true %}
const gridOptions = {
    // disable sorting on all columns
    defaultColDef: {
        sortable: false
    },
    columnDefs: [
        // Override default to enable sorting by name
        { field: 'name', sortable: true },
        { field: 'age' },
        { field: 'address' },
    ],
}
```

## Custom Sorting

{% metaTag tags=["sortModel"] /%}

Custom sorting is provided at a column level by configuring a comparator on the column definition.

{% apiDocumentation source="column-properties/properties.json" section="sort" names=["comparator"] /%}

```{% frameworkTransform=true spaceBetweenProperties=true %}
const gridOptions = {
    columnDefs: [
        {
            field: 'age',
            // simple number comparator
            comparator: (valueA, valueB, nodeA, nodeB, isDescending) => valueA - valueB
        },
        {
            field: 'name',
            // simple string comparator
            comparator: (valueA, valueB, nodeA, nodeB, isDescending) => {
                if (valueA == valueB) return 0;
                return (valueA > valueB) ? 1 : -1;
            }
        }
    ]
}
```

### Custom Sorting Example

Example below shows the following:

* Default sorting on the **Athlete** column.
* When the **Year** column is not sorted, it shows a custom icon (up/down arrow).
* The **Date** column has strings as the row data, but has a custom comparator so that when you sort this column it sorts as dates, not as strings.

{% gridExampleRunner title="Custom Sorting" name="custom-sorting" /%}

{% note %}
If you are using a custom column header component see [Custom Components](./column-headers/#custom-component/) for how to implement sorting.
{% /note %}


## Multi Column Sorting

It is possible to sort by multiple columns. The default action for multiple column sorting is for
the user to hold down {% kbd "⇧ Shift" /%} while clicking the column header. To change the default action to use
the {% kbd "^ Ctrl" /%} key (or {% kbd "Command" /%} key on Apple) instead set the property `multiSortKey='ctrl'`.

The example below demonstrates the following:

* The grid sorts by **Country** then **Athlete** by default.
* The property `multiSortKey='ctrl'` is set so multiple column sorting is achieved by holding down {% kbd "^ Ctrl" /%}
(or {% kbd "Command" /%} on Apple) and selecting multiple columns.

{% gridExampleRunner title="Multi Column Sort" name="multi-column" /%}

{% note %}
You can suppress the multi sorting behaviour by enabling the `suppressMultiSort` option, or force the behaviour without key press by enabling
the `alwaysMultiSort` option.
{% /note %}

## Sorting Animation

By default rows will animate after sorting. If you wish to suppress this animation set the grid property `animateRows=false`.

## Sorting Order

By default, the sorting order is as follows:

**ascending -> descending -> none**.

In other words, when you click a column that is not sorted, it will sort ascending. The next click
will make it sort descending. Another click will remove the sort.

It is possible to override this behaviour by providing your own `sortingOrder` on the `colDef`.

### Example: Sorting Order

The example below shows different combinations of sorting orders as follows:

* **Column Athlete:** ascending -> descending
* **Column Age:** descending -> ascending
* **Column Country:** descending -> no sort
* **Column Year:** ascending only
* **Default Columns:** descending -> ascending -> no sort

{% gridExampleRunner title="Sorting Order and Animation" name="sorting-order-and-animation" /%}

## Absolute Sorting
Absolute Sorting enables sorting numeric values based on their magnitude, ignoring their sign. This can be used to rank values by their size ignoring if a value is positive or negative.

### Example: Absolute Sorting

The example below shows how to use a column definition to sort by absolute value.

{% gridExampleRunner title="Absolute Value Sorting" name="absolute-sorting" /%}

In this example, the column `rankingChange` uses the following column definition:

```{% frameworkTransform=true %}

const gridOptions = {
    columnDefs: [
        // ... other columns 
        {
            field: 'rankingChange',
            sort: { direction: 'asc', type: 'absolute' },
            sortingOrder: [
                { direction: 'asc', type: 'absolute' }, 
                { direction: 'desc', type: 'absolute' },
                null, 
            ],
        },
    ],
};
```

{% apiDocumentation source="column-properties/properties.json" section="sort" names=["sort", "sortingOrder"] /%}

## Sorting API

{% note %}
The sort state can be saved and restored as part of [Grid State](./grid-state/).
{% /note %}

What sorting is applied is controlled via [Column State](./column-state/). The below examples uses the Column State API to control column sorting.

{% gridExampleRunner title="Sorting API" name="sorting-api" /%}

## Accented Sort

By default sorting doesn't take into consideration locale-specific characters. If you need to make your sort
locale-specific you can configure this by setting the grid option `accentedSort = true`.

Using this feature is more expensive; if you need to sort a very large amount of data, you might find that this
causes the sort to be noticeably slower.

The following example is configured to use this feature.

{% gridExampleRunner title="Accented Sort" name="accented-sort" exampleHeight=200 /%}

## Post-Sort

It is also possible to perform some post-sorting if you require additional control over the sorted rows.

This is provided via the `postSortRows` grid callback function as shown below:

{% apiDocumentation source="grid-options/properties.json" section="sort" names=["postSortRows"] /%}

```{% frameworkTransform=true %}
const gridOptions = {
    postSortRows: params => {
        let rowNodes = params.nodes;
        // here we put Ireland rows on top while preserving the sort order
        let nextInsertPos = 0;
        for (let i = 0; i < rowNodes.length; i++) {
            const country = rowNodes[i].data.country;
            if (country === 'Ireland') {
                rowNodes.splice(nextInsertPos, 0, rowNodes.splice(i, 1)[0]);
                nextInsertPos++;
            }
        }
    }
};
```

The following example uses this configuration to perform a post-sort on the rows. The custom function
puts rows with Ireland at the top always.

{% gridExampleRunner title="Post Sort" name="post-sort" /%}
